//
//  CommonBusinessModel.m
//  EUCIOS
//
//  Created by Khang on 4/9/13.
//  Copyright (c) 2013 Khang. All rights reserved.
//

#import "CommonBusinessModel.h"
#import <CommonCrypto/CommonDigest.h>

//Note for future
//    [ASIHTTPRequest setDefaultCache:[ASIDownloadCache sharedCache]];
//    [self.internalRequest setCachePolicy:ASIUseDefaultCachePolicy];
//    [self.internalRequest setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];


@interface CommonBusinessModel ()
@property (nonatomic, retain) ASIHTTPRequest* internalRequest;
@property (nonatomic, retain) ASIFormDataRequest* internalFormRequest;

- (void)doGetRequestWithUrl:(NSString*)url withParams:(NSMutableDictionary*)params;
- (void)doPostRequestWithUrl:(NSString*)url withParams:(NSMutableDictionary*)params;

- (void)cleanModel;
- (NSString*)md5HexDigest:(NSString*)input;
- (NSString*)genSig:(NSDictionary*)params withPriKey:(NSString*)prikey;
@end

@implementation CommonBusinessModel

- (id)init {
    if (self = [super init]) {
        self.dataResponse = [[[CommonBusinessResponse alloc] init] autorelease];
    }
    return self;
}

- (id)initWithBusinessType:(CommonBusinessType)type withResponseDelegate:(id<CommonBusinessModelDelegate>)response {
    if (self = [self init]) {
        self.businessType = type;
        self.delegate = response;
        
        self.dataResponse.commonBusinessType = self.businessType;
        self.dataResponse.commonModel = self;
    }
    return self;
}

- (void)dealloc {
    _delegate = nil;
    RELEASE(_dataResponse);
    
    [self cleanModel];
    
    [super dealloc];
}

- (void)cleanModel {
    if (_internalRequest) {
        [_internalRequest clearDelegatesAndCancel];
        RELEASE(_internalRequest);
    }
    if (_internalFormRequest) {
        [_internalFormRequest clearDelegatesAndCancel];
        RELEASE(_internalFormRequest);
    }
}

NSComparisonResult (^sortParams)(id, id) = ^(id obj1, id obj2) {
    return [obj1 compare:obj2 options:NSCaseInsensitiveSearch];
};

#pragma mark -
#pragma mark Private
- (NSString*)md5HexDigest:(NSString*)input {
	const char* str = [input UTF8String];
	unsigned char result[CC_MD5_DIGEST_LENGTH];
	CC_MD5(str, strlen(str), result);
	
	NSMutableString *hexDigest = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
	for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
		
		[hexDigest appendFormat:@"%02x", result[i]];
	}
	
	return hexDigest;
}

- (NSString*)genSig:(NSDictionary*)params withPriKey:(NSString*)prikey {
	
	NSMutableString* joined = [NSMutableString string];
	
	NSArray* keys = [params.allKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
	
	for (id obj in [keys objectEnumerator]) {
		id value = [params valueForKey:obj];
		if ([value isKindOfClass:[NSString class]]) {
			[joined appendString:obj];
            [joined appendString:@"="];
			[joined appendString:value];
		}
	}
	
	if (prikey) {
		[joined appendString:prikey];
	}
	
	return [self md5HexDigest:joined];
}

- (void)doGetRequestWithUrl:(NSString *)url withParams:(NSMutableDictionary *)params {
    [self cleanModel];
    
    NSString* stringRequest = [NSString stringWithFormat:@"%@", url];
    NSArray* keys = [params allKeys];
    for (NSInteger index = 0; index < [keys count]; index ++) {
        NSString* key = [keys objectAtIndex:index];
        NSString* next = [NSString stringWithFormat:@"%@=%@", key, [params objectForKey:key]];
        
        if (index == [keys count] - 1) {
            stringRequest = [stringRequest stringByAppendingFormat:@"%@", next];
        } else {
            stringRequest = [stringRequest stringByAppendingFormat:@"%@&", next];
        }
    }
    
    NSString* sig = [self genSig:params withPriKey:PRI_KEY];
    stringRequest = [stringRequest stringByAppendingFormat:@"&sig=%@", sig];    
    stringRequest = [stringRequest stringByAppendingFormat:@"&api_key=%@", PUB_KEY];
    
    NSLog(@"+ GET REQUEST: %@", stringRequest);
    
    self.internalRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:stringRequest]];
    [self.internalRequest setAllowCompressedResponse:YES];
    
    [self.internalRequest setStartedBlock:^{
        [self.dataResponse asiRequestBegin:self.internalRequest];
    }];
    
    [self.internalRequest setCompletionBlock:^{
        [self.dataResponse asiRequestFinish:self.internalRequest];
    }];
    
    [self.internalRequest setFailedBlock:^{
        [self.dataResponse asiRequestFail:self.internalRequest];
    }];
    
    [self.internalRequest startAsynchronous];    
}

- (void)doPostRequestWithUrl:(NSString *)url withParams:(NSMutableDictionary *)params {
    [self cleanModel];
    
    NSString* sig = [self genSig:params withPriKey:PRI_KEY];
    if (sig) {
        [params setObject:sig forKey:@"sig"];
    }
    
    [params setObject:PUB_KEY forKey:@"api_key"];

    NSLog(@"+ POST REQUEST: %@", params);
    
    self.internalFormRequest = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:url]];
    [self.internalFormRequest setAllowCompressedResponse:YES];
    NSArray* keys = [params allKeys];
    for (id key in keys) {
        [self.internalFormRequest setPostValue:[params objectForKey:key] forKey:key];
    }
    
    [self.internalFormRequest setStartedBlock:^{
        [self.dataResponse asiRequestBegin:self.internalFormRequest];
    }];
    [self.internalFormRequest setCompletionBlock:^{
        [self.dataResponse asiRequestFinish:self.internalFormRequest];
    }];
    [self.internalFormRequest setFailedBlock:^{
        [self.dataResponse asiRequestFail:self.internalFormRequest];
    }];
    
    [self.internalFormRequest startAsynchronous];
}


////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////// JUST DEFINE BELOW ///////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////

#pragma mark -
#pragma mark CommonBusinessLogic
- (void)doSignUpAccount:(NSString *)username withDisplayname:(NSString *)displayname
           withBirthday:(NSString *)birthday withEmail:(NSString *)email withPassword:(NSString *)pass
          withTwitterId:(NSString *)twitterid withFacebookId:(NSString *)facebookid
{
    self.businessType = kCommonBusinessTypeSignup;
    self.dataResponse.commonBusinessType = self.businessType;
    
    NSString* domainUrl = [NSString stringWithFormat:@"%@/api/user/doRegister?", API_DOMAIN];
    NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   [NSString stringWithString:username], @"name",
                                   [NSString stringWithString:displayname], @"display_name",
                                   [NSString stringWithString:birthday], @"dob",
                                   [NSString stringWithString:email], @"email",
                                   [NSString stringWithString:pass], @"pwd",
                                   [NSString stringWithString:twitterid], @"twitter_id",
                                   [NSString stringWithString:facebookid], @"facebook_id",
                                   nil];
    [self doPostRequestWithUrl:domainUrl withParams:params];
}

- (void)doSignInWithName:(NSString *)username withPassword:(NSString *)pass {
    self.businessType = kCommonBusinessTypeSignin;
    self.dataResponse.commonBusinessType = self.businessType;
    
    NSString* domainUrl = [NSString stringWithFormat:@"%@/api/user/doLogin?", API_DOMAIN];
    NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   [NSString stringWithString:username], @"name",
                                   [NSString stringWithString:pass], @"pwd",
                                   nil];
    [self doPostRequestWithUrl:domainUrl withParams:params];
}

@end
